package leetcode.array;

/**
 * @author Cheng Jun
 * Description: 已知一个长度为 n 的数组，预先按照升序排列，经由 1 到 n 次 旋转 后，得到输入数组。
 * 例如，原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到：
 * 若旋转 4 次，则可以得到 [4,5,6,7,0,1,2]
 * 若旋转 7 次，则可以得到 [0,1,2,4,5,6,7]
 * 注意，数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
 *
 * 给你一个元素值 可能重复 的数组 nums ，它原来是一个升序排列的数组，并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * @version 1.0
 * @date 2022/1/26 22:19
 * @see minArray
 */
public class findMin2 {

    // 思路：二分查找
    // 3 4 5 1 2
    // 5 1 2 3 4
    // 4 5 1 2 3
    // 2 1 2 2 2
    static public int findMin1(int[] numbers) {
        int left = 0;
        int right = numbers.length - 1;
        while (left <= right) {
            // 如果左右指针相等，表示定位到了最小值位置
            if (left == right) return numbers[left];
            int mid = (right - left) / 2 + left;
            // 如果 右边值比中间值还小，就表示最小值在右边（不包括中间位置）
            if (numbers[right] < numbers[mid]) {
                left = mid + 1;
                continue;
            }
            // 如果 左边值比中间值还小，就表示最小值在左边（包括中间位置）
            if (numbers[left] > numbers[mid]) {
                right = mid;
                continue;
            }
            // 如果上面 两种情况都不满足的话，就 右指针向中间移动一位
            right--;
        }
        return numbers[0];
    }

}
